home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 September / PCWorld_2008-09_cd.bin / v cisle / sadanastroju / delicious_bookmarks-2.0.64-fx.xpi / chrome / deliciousBookmarks.jar / content / ybookmarksUtils.js < prev    next >
Encoding:
JavaScript  |  2008-06-19  |  38.8 KB  |  983 lines

  1. /*
  2.  * This file has all the utility functions required by popup, dialog and main window
  3. */
  4. var YB_PLATFORM_MAC = "mac";
  5. var YB_PLATFORM_WIN = "win";
  6. var YB_PLATFORM_UNIX = "unix";
  7.  
  8. var YB_FIREFOX_BOOKMARK_FILE = "bookmarks.html";
  9. var YB_FIREFOX_PLACES_BOOKMARK_FILE = "bookmarks.postplaces.html";
  10. var YB_FIREFOX_PLACES_EXPORT_BOOKMARK_FILE = "ybookmarks.exportplaces.html";
  11. var YB_EXTENSION_MODE_CLASSIC = "classic";
  12. var YB_EXTENSION_MODE_STANDARD = "standard";
  13.  
  14. var ybookmarksUtils = {
  15.   _platform: null,
  16.   _prefs: null,
  17.   _DOTCOMHOST: ".delicious.com",
  18.   _DOTUSHOST: ".del.icio.us",
  19.   
  20.   openWindow: function(url, title, width, height) {
  21.     width = (width?width:300);
  22.     height = (height?height:300);
  23.  
  24.     // get window service
  25.     var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"].
  26.               getService(Components.interfaces.nsIWindowWatcher);
  27.     var options = "centerscreen,resizable,width=" + width + ",height=" + height;
  28.     var win = ww.openWindow( null, url, title, options, null );
  29.     return win;
  30.   },
  31.   
  32.   openPreferences : function(panelTabName) {
  33.  
  34.      setTimeout(function(panelTabName){ ybookmarksUtils._openPreferencesTab(panelTabName); }, 100, panelTabName);
  35.      openPreferences("paneBookmarks");
  36.   },
  37.    
  38.   _openPreferencesTab : function(panelTabName) {
  39.     
  40.     var wm = Components.classes[ "@mozilla.org/appshell/window-mediator;1" ]
  41.                            .getService( Components.interfaces.nsIWindowMediator );
  42.     var ref = wm.getMostRecentWindow("Browser:Preferences");
  43.     if (ref) {
  44.        var box, panel, tab;
  45.        box = ref.window.document.getElementById( "bookmarksPrefs" );
  46.        tab = ref.window.document.getElementById( "tab_" + panelTabName );
  47.        panel = ref.window.document.getElementById( "tbp_" + panelTabName );
  48.        if ( ( box != null ) && ( panel != null ) && ( tab != null ) ) {
  49.           box.selectedTab = tab;
  50.           box.selectedPanel = panel;
  51.        }
  52.     }
  53.   },
  54.   
  55.   /**
  56.    * Get the user's profile directory
  57.    */
  58.   getProfileDir : function() {
  59.     var dirService = Components.classes["@mozilla.org/file/directory_service;1"].
  60.                      getService(Components.interfaces.nsIProperties);
  61.     var profileDir = dirService.get("ProfD", Components.interfaces.nsILocalFile);
  62.  
  63.     return profileDir;
  64.   },
  65.   
  66.   /**
  67.    * Return the string contents of a file
  68.    * @param aFilename the name of the file
  69.    */  
  70.   fileContentsAsString : function(aFilename) {
  71.     try {
  72.         var fileString = "";        
  73.         var file = Components.classes["@mozilla.org/file/local;1"]
  74.                 .createInstance(Components.interfaces.nsILocalFile);
  75.         file.initWithPath(aFilename);
  76.         var fis = Components.classes["@mozilla.org/network/file-input-stream;1"]
  77.                                            .createInstance(Components.interfaces.nsIFileInputStream);
  78.         fis.init(file, 0x01, -1, 0);        
  79.         var charset = "UTF-8";
  80.         var bufSize = 4096;
  81.         const replacementChar = Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER;
  82.         var is = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
  83.                    .createInstance(Components.interfaces.nsIConverterInputStream);
  84.         is.init(fis, charset, bufSize, replacementChar);
  85.         var str = {};
  86.         while (is.readString(bufSize, str) != 0) {
  87.           fileString += str.value;          
  88.         }
  89.     } catch(e) {
  90.         yDebug.print("fileContentsAsStringNew()::=>  Error reading file: " + aFilename + " Exception:" + e, YB_LOG_MESSAGE);        
  91.         fileString = null;        
  92.     } finally {
  93.         if (is) { is.close(); }
  94.         if (fis) { fis.close(); }
  95.     }
  96.     return fileString;
  97.   
  98.   },
  99.   
  100.   getUnicodePref: function(prefName, prefBranch) {
  101.       return prefBranch.getComplexValue(prefName, Components.interfaces.nsISupportsString).data;
  102.   },
  103.  
  104.   setUnicodePref: function (prefName, prefValue, prefBranch) {
  105.       var sString = Components.classes["@mozilla.org/supports-string;1"].
  106.                       createInstance(Components.interfaces.nsISupportsString);
  107.       sString.data = prefValue;
  108.  
  109.       prefBranch.setComplexValue(prefName,  Components.interfaces.nsISupportsString, sString);
  110.   },
  111.   
  112.   getPlatform : function(){
  113.     if (this._platform == null) {
  114.       var platform = new String(navigator.platform);
  115.       if(!platform.search(/^Mac/)) 
  116.          this._platform = YB_PLATFORM_MAC;
  117.       else if(!platform.search(/^Win/))
  118.          this._platform = YB_PLATFORM_WIN;
  119.       else 
  120.          this._platform = YB_PLATFORM_UNIX;
  121.     }
  122.     
  123.     return this._platform; 
  124.   },
  125.    
  126.    
  127.   importStatusCallback: {
  128.        _notify: function(subject, topic, data) {
  129.              var os = Components.classes["@mozilla.org/observer-service;1"]
  130.                          .getService(Components.interfaces.nsIObserverService);
  131.              var xpcData = Components.classes["@mozilla.org/supports-string;1"].
  132.                                         createInstance(Components.interfaces.nsISupportsString);
  133.               var xpcSubject = Components.classes["@mozilla.org/supports-string;1"].
  134.                                         createInstance(Components.interfaces.nsISupportsString);
  135.               xpcSubject.data = subject;
  136.               xpcData.data = data;
  137.               os.notifyObservers(xpcSubject, "ybookmark.importBookmarks", xpcData);
  138.         },
  139.         
  140.         onload: function(result) {
  141.           var propertyBag = result.queryElementAt(0, Components.interfaces.nsIPropertyBag);
  142.           var status = propertyBag.getProperty("status");  
  143.           yDebug.print("getImportstatus callback: onload: " + status);
  144.           //complete", "importing" or "failed
  145.           this._notify("importProgress", "ybookmark.importBookmarks", status); 
  146.             
  147.         },
  148.       
  149.         onerror: function(event) {
  150.           yDebug.print("getImportStatus callback: onerror ");
  151.           this._notify("importError", "ybookmark.importBookmarks", null);
  152.           //yDebug.print("importBookmark callback: notified observers");
  153.           
  154.         }      
  155.   },
  156.   
  157.   exportPlacesToHtml : function() {
  158.     
  159.     try {
  160.         var file = Components.classes["@mozilla.org/file/directory_service;1"]
  161.                          .getService(Components.interfaces.nsIProperties)
  162.                          .get("ProfD", Components.interfaces.nsIFile);
  163.         file.append(YB_FIREFOX_PLACES_EXPORT_BOOKMARK_FILE);
  164.         if( !file.exists() || !file.isFile() ) {   // if it doesn't exist, create
  165.            file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0777);
  166.         }            
  167.         var localFile = Components.classes["@mozilla.org/file/local;1"].
  168.                 createInstance(Components.interfaces.nsILocalFile);
  169.         localFile.initWithPath(file.path);        
  170.         var exporter = Components.classes["@mozilla.org/browser/places/import-export-service;1"].
  171.                          getService(Components.interfaces.nsIPlacesImportExportService);
  172.         exporter.exportHTMLToFile(localFile);           
  173.     } catch(e) {
  174.       yDebug.print("Exception in exportPlacesToHtml(): "  + e, YB_LOG_MESSAGE);
  175.     }
  176.     
  177.   },
  178.   
  179.   startImport : function(userTags, addPopularTags, overwrite, filePath, email, priv) {
  180.     
  181.     try {   
  182.         var bookmarksString;
  183.         var xpcUserTags;
  184.         if (!filePath || filePath.length == 0) {
  185.               var profileDir = this.getProfileDir();        
  186.               //If FF3 or more use different filename        
  187.               if(ybookmarksUtils.getFFMajorVersion() > 2) {                              
  188.                   this.exportPlacesToHtml(); 
  189.                   profileDir.append(YB_FIREFOX_PLACES_EXPORT_BOOKMARK_FILE);                
  190.               } else {              
  191.                   profileDir.append(YB_FIREFOX_BOOKMARK_FILE);
  192.               }      
  193.               if (profileDir.isFile()) {
  194.                 profileDir.QueryInterface(Components.interfaces.nsIFile);
  195.                 filePath = profileDir.path;
  196.                 bookmarksString = ybookmarksUtils.fileContentsAsString(filePath);                
  197.                 //Delete the temporary file
  198.                 if(ybookmarksUtils.getFFMajorVersion() > 2) {                 
  199.                      profileDir.remove(false);
  200.                 }
  201.               }
  202.         }
  203.         else {      
  204.             var file = Components.classes["@mozilla.org/file/local;1"]
  205.                 .createInstance(Components.interfaces.nsILocalFile);
  206.             file.initWithPath(filePath);
  207.             if (file.isFile()) {
  208.               bookmarksString = ybookmarksUtils.fileContentsAsString(filePath);
  209.             }  
  210.         }    
  211.     } catch(e) {
  212.         yDebug.print("Exception in ybookmarksutils::startImport(): "  + e, YB_LOG_MESSAGE);
  213.     }
  214.     this.startImportWithBookmarksString(userTags, addPopularTags, overwrite, encodeURIComponent(bookmarksString),email, priv);
  215.     
  216.   },
  217.   
  218.   //Note that bookmarksString is URIencoded.  
  219.   startImportWithBookmarksString : function(userTags, addPopularTags, overwrite, bookmarksString, email, priv)  {
  220.  
  221.       var xpcUserTags = Components.classes["@mozilla.org/array;1"]
  222.                            .createInstance(Components.interfaces.nsIMutableArray);
  223.  
  224.       for (var i = 0; i < userTags.length; i++) {
  225.         var tag = Components.classes["@mozilla.org/supports-string;1"].
  226.                     createInstance(Components.interfaces.nsISupportsString);
  227.         tag.data = userTags[i];
  228.         xpcUserTags.appendElement(tag, false);
  229.       }
  230.        
  231.       var ssr = Components.classes["@yahoo.com/socialstore/delicious;1"].
  232.          getService(Components.interfaces.nsISocialStore);           
  233.         
  234.       var cb = {
  235.         
  236.          _getStatus: function () {
  237.             var ssr = Components.classes["@yahoo.com/socialstore/delicious;1"].
  238.                   getService(Components.interfaces.nsISocialStore);          
  239.  
  240.            //complete", "importing" or "failed
  241.            ssr.getImportStatus(ybookmarksUtils.importStatusCallback);
  242.          },
  243.          
  244.          onload: function(result) {
  245.            var propertyBag = result.queryElementAt(0, Components.interfaces.nsIPropertyBag);
  246.            var status = propertyBag.getProperty("status");  
  247.            yDebug.print("cb.onload: " + status);
  248.            this._getStatus(); 
  249.          },
  250.          
  251.          onerror: function(event) {
  252.             yDebug.print("cb.error", YB_LOG_MESSAGE);
  253.             this._getStatus();
  254.          }
  255.       };
  256.     
  257.       //"accepted" or "busy"
  258.       ssr.importBookmarks(bookmarksString, xpcUserTags, addPopularTags, overwrite, parseInt(email), parseInt(priv), cb);
  259.   },
  260.  
  261.   openTag: function(tag, aEvent) {
  262.       var where = whereToOpenLink(aEvent);      
  263.       openUILinkIn(deliciousService.getUrl("popular/" + tag), where);
  264.   },
  265.  
  266.   openBookmark: function(aEvent, where) {
  267.     var type = aEvent.target.getAttribute( "type" );
  268.     if ( type == "http://home.netscape.com/NC-rdf#Bookmark" || type == "http://home.netscape.com/NC-rdf#MicsumBookmark") {  
  269.       var url = aEvent.target.getAttribute( "url" );
  270.       //need to manually close the menupopup
  271.       if(aEvent.button == 1)
  272.         ybBookmarksMenu.closeMenuPopup(aEvent.target);
  273.  
  274.       if (!where) {
  275.         // hack for tabs mix plus
  276.         if (!ybookmarksUtils._prefs) {
  277.           ybookmarksUtils._prefs = Components.classes["@mozilla.org/preferences-service;1"]
  278.                         .getService(Components.interfaces.nsIPrefBranch);
  279.         }
  280.         var tabMixPlusOpenInTab = false;
  281.         try {
  282.           // tabsmixplus open all bookmarks in new tab
  283.           tabMixPlusOpenInTab = ybookmarksUtils._prefs.getBoolPref("extensions.tabmix.opentabfor.bookmarks");
  284.         } catch (e) {}
  285.         
  286.         if (tabMixPlusOpenInTab) {
  287.           where = "tab";
  288.         } else {
  289.           where = whereToOpenLink(aEvent);
  290.         }
  291.       }
  292.       openUILinkIn ( url, where );
  293.     }
  294.   },
  295.   
  296.   
  297.   getTopWindow : function() {
  298.       
  299.       var windowManager = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService();
  300.       var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
  301.       var topWindow = windowManagerInterface.getMostRecentWindow( "navigator:browser" );
  302.     
  303.       return topWindow;
  304.   },
  305.  
  306.   /**
  307.    * returns character index of tag if found, -1 otherwise
  308.    */
  309.   containsTag: function( str, tag ) {
  310.     var retval = -1;
  311.     var startIndex = 0;
  312.     var idx;
  313.     do {
  314.       idx = str.indexOf( tag, startIndex );
  315.       if( idx != -1 ) {
  316.         if( ( ( idx == 0 ) || ( str[ idx - 1 ] == ' ' ) ) && 
  317.           ( ( idx + tag.length == str.length ) || ( str[ idx + tag.length ] == ' ' ) ) ) {
  318.             retval = idx;
  319.           }
  320.         startIndex += tag.length;
  321.       }
  322.     } while( ( idx != -1 ) && ( startIndex < str.length ) && ( retval == -1 ) );
  323.     return retval;
  324.   },
  325.   
  326.   /**
  327.     * Convert the timestamp from del API to a UI friendly string.  Use this to
  328.     * keep the Date strings in the UI maintainably consistent.
  329.     */
  330.   usecToUIString: function(usec) {
  331.     var date = new Date (usec / 1000);
  332.     var str = date.toLocaleDateString() + " " + date.toLocaleTimeString();
  333.     return str;
  334.   },
  335.   
  336.   jsStringToNs: function(jsString) {
  337.     var nsString = Components.classes["@mozilla.org/supports-string;1"]
  338.                     .createInstance(Components.interfaces.nsISupportsString);
  339.     nsString.data = jsString;
  340.     
  341.     return nsString;
  342.   },
  343.   
  344.   jsArrayToNs: function(jsArray) {
  345.     var nsArray = Components.classes["@mozilla.org/array;1"]
  346.                     .createInstance(Components.interfaces.nsIMutableArray);
  347.  
  348.     for ( var counter = 0; counter < jsArray.length; ++counter ) {
  349.       var str = ybookmarksUtils.jsStringToNs(jsArray[counter]);
  350.       nsArray.appendElement ( str, false );
  351.     }
  352.  
  353.     return nsArray;
  354.   },
  355.   
  356.   nsArrayToJs: function(nsArray) {
  357.     var result = [];
  358.     nsArray.QueryInterface(Components.interfaces.nsIArray);
  359.     var nsEnum = nsArray.enumerate();
  360.     while (nsEnum.hasMoreElements()) {
  361.       var e = nsEnum.getNext();
  362.       e.QueryInterface(Components.interfaces.nsISupportsString);
  363.       result.push(e.data);
  364.     }
  365.     return result;
  366.   },
  367.   
  368.   nsBundleToJs: function(nsBundle) {
  369.     var result = { name:  nsBundle.name,
  370.                    tags:  ybookmarksUtils.nsArrayToJs(nsBundle.tags),
  371.                    order: nsBundle.order };
  372.     return result;
  373.   },
  374.   
  375.   uniqueBookmarkArray: function(aArray) {
  376.     var table = {};
  377.     var result = [];
  378.     for (var i=0; i < aArray.length; i++ ) {
  379.       var bm = aArray[i];
  380.       if (!table[bm.url]) {
  381.         table[bm.url] = bm;
  382.       }
  383.     }
  384.     for (url in table) {
  385.       result.push(table[url]);
  386.     } 
  387.      return result;
  388.     },
  389.   
  390.   CC                        : Components.classes,
  391.   CI                        : Components.interfaces,
  392.   gNC_NS                    : "http://home.netscape.com/NC-rdf#",
  393.   gRDF_NS                   : "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
  394.   gWEB_NS                   : "http://home.netscape.com/WEB-rdf#",
  395.   NS_BOOKMARK_BASE          : "http://www.mozilla.org/bookmark#",
  396.   nsIRDFLiteral             : Components.interfaces.nsIRDFLiteral,
  397.  
  398.   bindMethod                : function(obj, fn) { return function() { fn.apply(obj, arguments); } },
  399.   getService                : function(classx, interfacex) { return ybookmarksUtils.CC[classx].getService(ybookmarksUtils.CI[interfacex]); },
  400.   addObserver               : function(subject) { ybookmarksUtils.observerService.addObserver(this, subject, false); },
  401.   removeObserver            : function(subject) { ybookmarksUtils.observerService.removeObserver(this, subject); },
  402.   getResource               : function(resourceUri) { return this.gRdfService.GetResource(resourceUri); },
  403.  
  404.   importSymbols             : function(scope) {
  405.       for (var i = 1; i < arguments.length; i++) {
  406.           var value = ybookmarksUtils[arguments[i]];
  407.           //yDebug.print("Importing \"" + arguments[i] + "\" = \"" + value + "\" from ybookmarksUtils");
  408.           if (!value) {
  409.               yDebug.print("WARNING: \"" + arguments[i] + "\" is not defined in ybookmarksUtils");
  410.           }
  411.           scope[arguments[i]] = value;
  412.       }
  413.   },
  414.  
  415.   /**
  416.    **  Searches given string for keywords. By default, it does a
  417.    **  disjunction search (returns true if str contains _ANY_ of the
  418.    **  keywords). Conjunction search can be specified using the last
  419.    **  arg
  420.    **/
  421.   searchStringForKeywords : function(str, keywords, conjunction) {
  422.       if (keywords.length == 0) return false;
  423.       if (conjunction == null) conjunction = false;
  424.  
  425.       str = str.toLowerCase();
  426.       var nValidKeywords = 0, nMatches = 0;
  427.       for (var i = 0; i < keywords.length; ++i) {
  428.           if (keywords[i].length > 0) {
  429.               ++nValidKeywords;
  430.               if (str.indexOf(keywords[i]) != -1) {
  431.                   if (!conjunction) return true; else ++nMatches;
  432.               }
  433.           }
  434.       }
  435.       if (nMatches == nValidKeywords) return true; // can only be conjunction
  436.       else return false;
  437.   },
  438.  
  439.   /**
  440.    **  Takes a string of text and wraps it to maxLength characters per
  441.    **  line.  The return value is an array of lines, where each line
  442.    **  is a string and line.length <= maxLength
  443.    **/
  444.   lineWrap                  : function(content, maxLength) {
  445.       var arrLines = [];
  446.       var words = content.split(' ');
  447.       var currLineWords = [];
  448.       var currLineLength = 0;
  449.       for (var i = 0; i < words.length; i++) {
  450.           var word = words[i];
  451.           if (word.length > maxLength) {
  452.               ybookmarksUtils.arrayInsertAt(words, i + 1, word.slice(maxLength));
  453.               word = word.slice(0, maxLength);
  454.           }
  455.           if (currLineLength + word.length > maxLength) {
  456.               arrLines.push(currLineWords.join(' '));
  457.               currLineWords = [word];
  458.               currLineLength = word.length;
  459.           } else {
  460.               currLineWords.push(word);
  461.               currLineLength += word.length;
  462.           }
  463.       }
  464.       if (currLineLength > 0) {
  465.           arrLines.push(currLineWords.join(' '));
  466.       }
  467.       return arrLines;
  468.   },
  469.  
  470.   removeAllChildren         : function(node) {
  471.       while (node.firstChild) {
  472.           node.removeChild(node.firstChild);
  473.       }
  474.   },
  475.  
  476.   /**
  477.    **  The JavaScript Array.splice method can only splice single
  478.    **  elements into an array. If you needed to splice an array into
  479.    **  an array, you could call Array.splice repeatedly, but this is
  480.    **  very inefficient because it has to repeatedly shift the
  481.    **  contents of the array. This function is more efficient; it
  482.    **  simply returns a new array with childrenToInsert spliced into
  483.    **  arr.
  484.    **/
  485.   arraySplice               : function(arr, row, childrenToInsert) {
  486.       return arr.slice(0, row).concat(childrenToInsert, arr.slice(row));
  487.   },
  488.  
  489.   /**
  490.    **  This function simply inserts an element at a given position in
  491.    **  an array.  It knows to append the new element if it's going at
  492.    **  the end of the array; otherwise it does an Array.splice
  493.    **/
  494.   arrayInsertAt             : function(arr, pos, elem) {
  495.       var length = arr.length;
  496.       if (pos == length) {
  497.           arr[pos] = elem;           // Append
  498.       } else if (pos < length) {
  499.           arr.splice(pos, 0, elem);  // Insert into using splice
  500.       } else {
  501.           alert("arrayInsertAt: pos = " + pos + ": something went wrong!");
  502.       }
  503.   },
  504.  
  505.   /**
  506.    **  Return the index of the first element in the array arr for
  507.    **  which the function fn evaluates to true.
  508.    **/
  509.   linearSearch              : function (arr, fn) {
  510.       var length = arr.length;
  511.       for (var i = 0; i < length; i++) {
  512.           if (fn(arr[i])) return i;
  513.       }
  514.       return -1;
  515.   },
  516.  
  517.   /**
  518.    **  Binary search for an element in a *sorted* array.
  519.    **  Array must be in sorted order, as defined by the comparator function.
  520.    **  If elem is found, then its index is returned.
  521.    **  If elem is not found, then a negative number is returned which
  522.    **  indicates where elem would go.
  523.    **/
  524.   binarySearch              : function(arr, elem, comparator) {
  525.       var low = 0, high = arr.length - 1, mid = 0;
  526.  
  527.       while (low <= high) {
  528.           mid = low + Math.floor((high - low) / 2);
  529.           var comparatorResult = comparator(elem, arr[mid]);
  530.           if (comparatorResult > 0) low = mid + 1;
  531.           else if (comparatorResult < 0) high = mid - 1;
  532.           else return mid;
  533.       }
  534.       return -low -  1;
  535.   },
  536.  
  537.   /**
  538.    **  This function defines a getter function for an object property.
  539.    **  Furthermore, the output of the function is memoized (i.e.: cached)
  540.    **  so that further reads of this property come out of the cache instead
  541.    **  of calling the function again. For expensive functions, memoizing
  542.    **  can result in great gains in efficiency.
  543.    **
  544.    **  Sample usage:
  545.    **
  546.    **  Tag.prototype.memoizeGetter = memoizeGetter;
  547.    **  Tag.prototype.memoizeGetter("NumBookmarks", function() { 
  548.    **      return bookmarksStore.getTotalBookmarksForTag(this.Name);
  549.    **  });
  550.    **/
  551.   memoizeGetter             : function(name, func) {
  552.       this.__defineGetter__(name, function() {
  553.           if (!this.cache) this.cache = {};
  554.           var fromCache = this.cache[name];
  555.           if (typeof fromCache != "undefined") {
  556.               return fromCache;
  557.           } else {
  558.               return this.cache[name] = func.apply(this, arguments);
  559.           }
  560.       });
  561.   },
  562.  
  563.   /**
  564.    **  Similar to Array.map, but for an nsISimpleEnumerator. 
  565.    **  Returns an array containing the results of applying the
  566.    **  function func to each element coming from an
  567.    **  nsISimpleEnumerator.
  568.    **/
  569.   enumeratorMap             : function(enumerator, func) {
  570.       var ret               = [];
  571.       var hasMoreElements   = enumerator.hasMoreElements;
  572.       var getNext           = enumerator.getNext;
  573.  
  574.       while (hasMoreElements()) {
  575.           var val = func(getNext());
  576.           if (val) ret[ret.length] = val;
  577.       }
  578.       
  579.       return ret;
  580.   },
  581.  
  582.   getTagsEnumerator         : function() {
  583.       return this.gRdfContainerUtils.MakeSeq(this.bookmarksDataSource, this.grscTagRoot).GetElements();
  584.   },
  585.            
  586.   createISupportsArray      : function() {
  587.       return Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsISupportsArray);
  588.   },
  589.   get gRdfService()         { return this.getService("@mozilla.org/rdf/rdf-service;1", "nsIRDFService"); },
  590.   get gRdfContainerUtils()  { return this.getService("@mozilla.org/rdf/container-utils;1", "nsIRDFContainerUtils"); },
  591.   get bookmarksStore()      { return this.getService("@mozilla.org/ybookmarks-store-service;1", "nsIYBookmarksStoreService"); },
  592.   get socialStore()         { return this.getService("@yahoo.com/socialstore/delicious;1", "nsISocialStore"); },
  593.   get prefs()               { return this.getService("@mozilla.org/preferences-service;1", "nsIPrefBranch"); },
  594.   get observerService()     { return this.getService("@mozilla.org/observer-service;1", "nsIObserverService"); },
  595.   get atomService()         { return this.getService("@mozilla.org/atom-service;1", "nsIAtomService"); },
  596.   get bookmarksDataSource() { return this.bookmarksStore.getDataSource(); },
  597.  
  598.   get grscTag()             { return this.getResource(this.NS_BOOKMARK_BASE + "tag"); },
  599.   get grscTagValue()        { return this.getResource(this.NS_BOOKMARK_BASE + "tagvalue"); },
  600.   get grscChildCount()      { return this.getResource(this.gNC_NS + "ChildCount"); },
  601.   get grscTagRoot()         { return this.getResource("NC:YBookmarksTagRoot"); },
  602.   get grscBookmarksRoot()   { return this.getResource("NC:BookmarksRoot"); },
  603.   get grscName()            { return this.getResource(this.gNC_NS + "Name"); },
  604.   get grscDesc()            { return this.getResource(this.gNC_NS + "Description"); },
  605.   get grscShared()          { return this.getResource(this.NS_BOOKMARK_BASE + "shared"); },
  606.   get grscHash()            { return this.getResource(this.NS_BOOKMARK_BASE + "hash") },
  607.   get grscMetaHash()        { return this.getResource(this.NS_BOOKMARK_BASE + "metahash") },
  608.   get grscType()            { return this.getResource(this.gRDF_NS + "type"); },
  609.   get grscBookmarkType()    { return this.getResource(this.gNC_NS + "Bookmark"); },
  610.   get grscLivemarkType()    { return this.getResource(this.gNC_NS + "Livemark"); },
  611.   get grscUrl()             { return this.getResource(this.gNC_NS + "URL"); },
  612.   get grscShortcut()        { return this.getResource(this.gNC_NS + "ShortcutURL"); },
  613.   get grscVisitCount()      { return this.getResource(this.gNC_NS + "VisitCount"); },
  614.   get grscLastVisitDate()   { return this.getResource(this.gWEB_NS + "LastVisitDate"); },
  615.   get grscAddDate()         { return this.getResource(this.gNC_NS + "BookmarkAddDate"); },
  616.   get grscIcon()            { return this.getResource(this.gNC_NS + "Icon"); },
  617.  
  618.   getValue                  : function(datasource, subject, predicate, iface) {
  619.       var target = datasource.GetTarget(subject, predicate, true);
  620.       if (target) {
  621.           try {
  622.               return target.QueryInterface(iface).Value;
  623.           } catch (e) {
  624.               yDebug.print("*** Exception - " + e);
  625.               return null;
  626.           }
  627.       } else {
  628.           return null;
  629.       }
  630.   },
  631.   setCookie : function(cookieName, uri, cookieDomain, value, expireAfterDays){
  632.       yDebug.print("ybookmarkUtils.js::ybookmarkUtils::setCookie()=>Invoked",YB_LOG_MESSAGE);
  633.       try {
  634.      var ios = Components.classes["@mozilla.org/network/io-service;1"]
  635.              .getService(Components.interfaces.nsIIOService);
  636.     var uri = ios.newURI(uri, null, null);
  637.     var obj = Components.classes["@mozilla.org/cookieService;1"].getService(Components.interfaces.nsICookieService);
  638.  
  639.     var cookieValue = cookieName + "=" + value+ ";domain=" + cookieDomain;
  640.  
  641.     if (expireAfterDays > 0){
  642.         var expiryDate=new Date(); // today's date
  643.         expiryDate.setDate(expiryDate.getDate()+expireAfterDays);
  644.         cookieValue+= ";expires=" + expiryDate.toGMTString();
  645.     }
  646.     
  647.     yDebug.print("Creating Cookie => "+cookieValue, YB_LOG_MESSAGE);
  648.     obj.setCookieString(uri,null,cookieValue,null);
  649.       }catch (e){
  650.           yDebug.print("ybookmarkUtils.js::ybookmarkUtils::setCookie()=>Exception: "+e,YB_LOG_MESSAGE);
  651.       }
  652.   },
  653.   cookieExists : function(cookieName, cookieDomain){
  654.       yDebug.print("ybookmarkUtils.js::ybookmarkUtils::cookieExists()=>Invoked",YB_LOG_MESSAGE);
  655.       try {
  656.         var cookieManager = ( Components.classes[ "@mozilla.org/cookiemanager;1" ]
  657.                 .getService( Components.interfaces.nsICookieManager ) );
  658.         var iter = cookieManager.enumerator; 
  659.         while( iter.hasMoreElements() ) { 
  660.             var cookie = iter.getNext(); 
  661.             if( cookie instanceof Components.interfaces.nsICookie ) { 
  662.                 if( cookie.host == cookieDomain && cookie.name == cookieName ) {
  663.                     return true;
  664.                 }
  665.             }
  666.         }
  667.       }catch (e){
  668.           yDebug.print("ybookmarkUtils.js::ybookmarkUtils::cookieExists()=>Exception: "+e,YB_LOG_MESSAGE);
  669.       }
  670.     return false;
  671.   },
  672.   
  673.   bookmarkResource          : {
  674.       getUrl                : function(bookmarkResource) {
  675.           return ybookmarksUtils.getValue(ybookmarksUtils.bookmarksDataSource, 
  676.                                           bookmarkResource, 
  677.                                           ybookmarksUtils.grscUrl, 
  678.                                           ybookmarksUtils.nsIRDFLiteral);
  679.       }
  680.   },
  681.   
  682.       openLinkToNewTab: function(url) {
  683.           try {
  684.              var windowManager = ( Components.classes[ "@mozilla.org/appshell/window-mediator;1" ] ).getService();
  685.             var windowManagerInterface = windowManager.QueryInterface( Components.interfaces.nsIWindowMediator );
  686.             var browser = ( windowManagerInterface.getMostRecentWindow( "navigator:browser" ) ).getBrowser();
  687.             
  688.             var newTab = browser.addTab( url );
  689.             browser.selectedTab = newTab;
  690.           } catch (e) {
  691.               yDebug.print("ybookmarksUtils.js::ybookmarksUtils::openLinkToNewTab()=>Exception: "+e,YB_LOG_MESSAGE);
  692.           }
  693.      },
  694.      evaluateXPath: function(aNode, aExpr) {
  695.          try {
  696.               var xpe = new XPathEvaluator();
  697.               var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ?
  698.                 aNode.documentElement : aNode.ownerDocument.documentElement);
  699.               var result = xpe.evaluate(aExpr, aNode, nsResolver, 0, null);
  700.               var found = [];
  701.               var res;
  702.               while (res = result.iterateNext()) {
  703.                 found.push(res);
  704.               }
  705.               return found;
  706.          }catch(e){
  707.              yDebug.print("Exception in ybookmarksUtil.js::evaluateXPath() =>" + e,YB_LOG_MESSAGE);
  708.          }
  709. },
  710.     
  711.     getExtensionMode:  function() {
  712.         ybookmarksUtils._prefs = Components.classes["@mozilla.org/preferences-service;1"]
  713.                         .getService(Components.interfaces.nsIPrefBranch);
  714.         var mode = "" ;
  715.         try {
  716.             mode = ybookmarksUtils._prefs.getCharPref( "extensions.ybookmarks@yahoo.engine.current.mode");
  717.         } catch(e){}
  718.         if(mode == YB_EXTENSION_MODE_CLASSIC || mode == YB_EXTENSION_MODE_STANDARD) {
  719.             return mode;
  720.         } else {
  721.             return YB_EXTENSION_MODE_STANDARD;                        
  722.         }
  723.     },
  724.     
  725.     /**
  726.     * Closes all windows and restarts the browser.
  727.     * Based on http://lxr.mozilla.org/mozilla1.8/source/toolkit/mozapps/update/content/updates.js#1609
  728.     * If aRestart == true , Restart browser
  729.     */
  730.    _quit: function(aRestart) {
  731.    
  732.          // This process is *extremely* retarded. There should be some nice 
  733.          // integrated system for determining whether or not windows are allowed
  734.          // to close or not, and what happens when that happens. We need to 
  735.          // jump through all these hoops (duplicated from globalOverlay.js) to
  736.          // ensure that various window types (browser, downloads, etc) all 
  737.          // allow the app to shut down. 
  738.          // bsmedberg?     
  739.     
  740.          // Notify all windows that an application quit has been requested.
  741.          var os = Components.classes["@mozilla.org/observer-service;1"]
  742.                             .getService(Components.interfaces.nsIObserverService);
  743.          var cancelQuit = 
  744.              Components.classes["@mozilla.org/supports-PRBool;1"].
  745.              createInstance(Components.interfaces.nsISupportsPRBool);
  746.          os.notifyObservers(cancelQuit, "quit-application-requested", null);
  747.     
  748.          // Something aborted the quit process. 
  749.          if (cancelQuit.data)
  750.            return;
  751.     
  752.          // Notify all windows that an application quit has been granted.
  753.          os.notifyObservers(null, "quit-application-granted", null);
  754.     
  755.          // Enumerate all windows and call shutdown handlers
  756.          var wm =
  757.              Components.classes["@mozilla.org/appshell/window-mediator;1"].
  758.              getService(Components.interfaces.nsIWindowMediator);
  759.          var windows = wm.getEnumerator(null);
  760.          while (windows.hasMoreElements()) {
  761.            var win = windows.getNext();
  762.            if (("tryToClose" in win) && !win.tryToClose())
  763.              return;
  764.            }
  765.     
  766.          var appStartup = 
  767.              Components.classes["@mozilla.org/toolkit/app-startup;1"].
  768.              getService(Components.interfaces.nsIAppStartup);
  769.          if (aRestart) {
  770.            appStartup.quit(appStartup.eAttemptQuit | appStartup.eRestart);
  771.          }
  772.          else {
  773.            appStartup.quit(appStartup.eAttemptQuit);
  774.          }
  775.    },
  776.      
  777.     getFFMajorVersion: function () {
  778.         var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
  779.                         .getService(Components.interfaces.nsIXULAppInfo);
  780.  
  781.         return parseInt(appInfo.version);                     
  782.     },
  783.             
  784.    /**
  785.     * Function to check if the window is the recent window, can be used to make sure that the js function gets called only once 
  786.     *  even if there are mutiple windows.
  787.     *  Example if(isRecentWindow()) { import_bookmarks();}  //makes sure that function gets called only once 
  788.     */    
  789.     isRecentWindow: function () {
  790.         var wm =
  791.             Components.classes["@mozilla.org/appshell/window-mediator;1"].
  792.                getService(Components.interfaces.nsIWindowMediator);
  793.         if(wm.getMostRecentWindow("navigator:browser") == window) {
  794.             return true;
  795.         } else {
  796.             return false
  797.         }      
  798.     },    
  799.        
  800.    /**
  801.     * Function parses text and seperates anchors and adds style to them and make them work in XUL
  802.     */
  803.     parseTextForAnchors: function(text) {
  804.         if(!text) return;
  805.  
  806.         /**
  807.          * Make anchors live by replacing < and > to < and >
  808.          */
  809.         text = text.replace('href="', 'class="alertTextAnchor" onclick="ybookmarksUtils.openLinkToNewTab('+"'");
  810.         text = text.replace('">', "');"+'"'+">");
  811.  
  812.         return text;
  813.     },
  814.     
  815.     /**
  816.      * Copied from FF2 source to make things work in FF2 and FF3
  817.      */
  818.     getDescriptionFromDocument: function (aDocument) {
  819.         var metaElements = aDocument.getElementsByTagName('META');
  820.         for (var m = 0; m < metaElements.length; m++) {
  821.           if (metaElements[m].name.toLowerCase() == 'description' || metaElements[m].httpEquiv.toLowerCase() == 'description')
  822.             return metaElements[m].content;
  823.         }
  824.         return '';
  825.   },
  826.   getSelectionFromResource: function (aItem, aParent)
  827.   {
  828.     var selection    = {};
  829.     selection.length = 1;
  830.     selection.item   = [aItem  ];
  831.     selection.parent = [aParent];
  832.     this.checkSelection(selection);
  833.     return selection;
  834.   },
  835.   
  836.   isOSXLeopard: function()
  837.   {
  838.     var osDesc = window.navigator.oscpu;
  839.     //Mac OS X 10.5 - leopard
  840.     if(osDesc.indexOf("Mac OS X") == -1) {
  841.         return false; 
  842.     }    
  843.     return true;
  844.   },
  845.   
  846.   getServerPref: function(url, prefName) {
  847.     yDebug.print("ybookmarksUtils::getServerPref", YB_LOG_MESSAGE);        
  848.     var onload = function(event) {
  849.         yDebug.print("ybookmarksUtils::getServerPref::LOAD", YB_LOG_MESSAGE);     
  850.         if (!ssrDeliciousHelper._isValidResponse(event, false)) {
  851.            if(event.target) {
  852.                //Send the fail notification.
  853.                Components.classes["@mozilla.org/observer-service;1"]
  854.                 .getService(Components.interfaces.nsIObserverService)
  855.                 .notifyObservers(null, "ybookmark.webPrefValue", "server-pref-failed");  
  856.  
  857.                yDebug.print("ybookmarksUtils::getServerPref::Failed:" + event.target.status, YB_LOG_MESSAGE);
  858.            }
  859.         }     
  860.         var doc = event.target.responseXML;
  861.         yDebug.print(event.target.responseText);
  862.         var nodes = doc.getElementsByTagName(prefName);           
  863.         yDebug.print("value is ====== :" + nodes[0].textContent,  YB_LOG_MESSAGE);     
  864.         if(nodes.length > 0) {
  865.            domain = nodes[0].textContent;
  866.            if(domain == ".del.icio.us" || domain == ".delicious.com" || domain == "fallback") {            
  867.                //Send the notification.
  868.                Components.classes["@mozilla.org/observer-service;1"]
  869.                 .getService(Components.interfaces.nsIObserverService)
  870.                 .notifyObservers(null, "ybookmark.webPrefValue", domain);  
  871.            }
  872.         } 
  873.     };
  874.  
  875.     var onerror = function(event) {
  876.        //Send the fail notification.
  877.        Components.classes["@mozilla.org/observer-service;1"]
  878.         .getService(Components.interfaces.nsIObserverService)
  879.         .notifyObservers(null, "ybookmark.webPrefValue", "server-pref-failed");  
  880.  
  881.         yDebug.print("ybookmarksUtils::getServerPref::Failed:" + event.target.status, YB_LOG_MESSAGE);
  882.     };
  883.      
  884.     var req = 
  885.      Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].
  886.         createInstance(); 
  887.     req.open('GET', url, true); 
  888.     req.onload = onload;       
  889.     req.onerror = onerror;     
  890.     req.send(null);
  891.  },
  892.  
  893.   getPrefDomain: function() 
  894.   {
  895.     var pref = Components.classes["@mozilla.org/preferences-service;1"]
  896.                           .getService(Components.interfaces.nsIPrefBranch);    
  897.     var prefDomain = '.del.icio.us';
  898.     try {
  899.       prefDomain = pref.getCharPref("extensions.ybookmarks@yahoo.bookmark.prefdomain");                                    
  900.     } catch (e) {
  901.       yDebug.print("ybookmarksUtils::=> exception accessing preference prefDomain!!!", YB_LOG_MESSAGE);
  902.     }
  903.     return prefDomain;
  904.   },
  905.   
  906.   setPrefDomain: function(domain) 
  907.   {
  908.     try {
  909.        Components.classes["@mozilla.org/preferences-service;1"]
  910.                            .getService(Components.interfaces.nsIPrefBranch)
  911.                            .setCharPref("extensions.ybookmarks@yahoo.bookmark.prefdomain", domain);
  912.     } catch (e) {
  913.        yDebug.print("ybookmarksUtils::=> exception setting preference prefDomain:" + domain, YB_LOG_MESSAGE);
  914.     }
  915.   },
  916.   
  917.   /**
  918.     * Closes all windows and restarts the browser.
  919.     */
  920.   restartBrowser: function() {
  921.      this._quit(true);
  922.   },
  923.    
  924.    /**
  925.     * Closes all windows
  926.     */
  927.   quitBrowser: function() {
  928.      this._quit(false);
  929.   },
  930.    
  931.    /**
  932.     * Closes all windows and restarts the browser.
  933.     * Based on http://lxr.mozilla.org/mozilla1.8/source/toolkit/mozapps/update/content/updates.js#1609
  934.     */
  935.   _quit: function(aRestart) {
  936.    
  937.          // This process is *extremely* retarded. There should be some nice 
  938.          // integrated system for determining whether or not windows are allowed
  939.          // to close or not, and what happens when that happens. We need to 
  940.          // jump through all these hoops (duplicated from globalOverlay.js) to
  941.          // ensure that various window types (browser, downloads, etc) all 
  942.          // allow the app to shut down. 
  943.          // bsmedberg?     
  944.     
  945.          // Notify all windows that an application quit has been requested.
  946.          var os = Components.classes["@mozilla.org/observer-service;1"]
  947.                             .getService(Components.interfaces.nsIObserverService);
  948.          var cancelQuit = 
  949.              Components.classes["@mozilla.org/supports-PRBool;1"].
  950.              createInstance(Components.interfaces.nsISupportsPRBool);
  951.          os.notifyObservers(cancelQuit, "quit-application-requested", null);
  952.     
  953.          // Something aborted the quit process. 
  954.          if (cancelQuit.data)
  955.            return;
  956.     
  957.          // Notify all windows that an application quit has been granted.
  958.          os.notifyObservers(null, "quit-application-granted", null);
  959.     
  960.          // Enumerate all windows and call shutdown handlers
  961.          var wm =
  962.              Components.classes["@mozilla.org/appshell/window-mediator;1"].
  963.              getService(Components.interfaces.nsIWindowMediator);
  964.          var windows = wm.getEnumerator(null);
  965.          while (windows.hasMoreElements()) {
  966.            var win = windows.getNext();
  967.            if (("tryToClose" in win) && !win.tryToClose())
  968.              return;
  969.            }
  970.     
  971.          var appStartup = 
  972.              Components.classes["@mozilla.org/toolkit/app-startup;1"].
  973.              getService(Components.interfaces.nsIAppStartup);
  974.          if (aRestart) {
  975.            appStartup.quit(appStartup.eForceQuit | appStartup.eRestart);
  976.          }
  977.          else {
  978.            appStartup.quit(appStartup.eAttemptQuit);
  979.          }
  980.   }
  981.   
  982. };
  983.